using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Windy.Json
{
    public struct JsonNotation
    {
        #region Constructors

        private JsonNotation(JsonNotationType type, dynamic value)
            : this()
        {
            this.Type = type;
            this.Value = value;
        }

        public JsonNotation(JsonNotationType type)
            : this(type, null)
        { }

        public JsonNotation(string text)
            : this(JsonNotationType.String, text)
        { }

        public JsonNotation(decimal number)
            : this(JsonNotationType.Number, number)
        { }

        #region Number Conversion Constructor

        public JsonNotation(long number)
            : this((decimal)number)
        { }

        public JsonNotation(ulong number)
            : this((decimal)number)
        { }

        public JsonNotation(int number)
            : this((decimal)number)
        { }

        public JsonNotation(uint number)
            : this((decimal)number)
        { }

        public JsonNotation(short number)
            : this((decimal)number)
        { }

        public JsonNotation(ushort number)
            : this((decimal)number)
        { }

        public JsonNotation(byte number)
            : this((decimal)number)
        { }

        public JsonNotation(sbyte number)
            : this((decimal)number)
        { }


        public JsonNotation(float number)
            : this((decimal)number)
        { }

        public JsonNotation(double number)
            : this((decimal)number)
        { }

        #endregion

        #endregion

        #region Instance Members
        #region Properties
        public JsonNotationType Type { get; private set; }
        public dynamic Value { get; private set; }
        #endregion
        #region Format

        public override string ToString()
        {
            string format = null;
            switch (Type)
            {
                case JsonNotationType.Undefined:
                case JsonNotationType.String:
                case JsonNotationType.Number:
                    format = "{{{0}:{1}}}";
                    break;
                case JsonNotationType.True:
                case JsonNotationType.False:
                case JsonNotationType.Null:

                case JsonNotationType.ObjectBegin:
                case JsonNotationType.ObjectEnd:
                case JsonNotationType.ArrayBegin:
                case JsonNotationType.ArrayEnd:

                case JsonNotationType.NameSeperator:
                case JsonNotationType.MemberSeperator:

                    format = "{{{0}}}";
                    break;
                default:
                    format = "{{Unexpected Format {0}:{1}}}";
                    break;
            }

            return string.Format(format, Type, Value);
        }

        #endregion

        #endregion

        #region Static Memebers

        #region Factory Methods
        public static JsonNotation Create(string text)
        {
            return new JsonNotation(text);
        }
        public static JsonNotation CreateUnknown(string value)
        {
            return new JsonNotation(JsonNotationType.Undefined, value);
        }
        public static JsonNotation Create(decimal value)
        {
            return new JsonNotation(value);
        }
        #endregion

        #region Constant Fields
        public readonly static JsonNotation True = new JsonNotation(JsonNotationType.True);
        public readonly static JsonNotation False = new JsonNotation(JsonNotationType.False);
        public readonly static JsonNotation Null = new JsonNotation(JsonNotationType.Null);
        public readonly static JsonNotation ObjectBegin = new JsonNotation(JsonNotationType.ObjectBegin);
        public readonly static JsonNotation ObjectEnd = new JsonNotation(JsonNotationType.ObjectEnd);
        public readonly static JsonNotation ArrayBegin = new JsonNotation(JsonNotationType.ArrayBegin);
        public readonly static JsonNotation ArrayEnd = new JsonNotation(JsonNotationType.ArrayEnd);
        public readonly static JsonNotation NameSeperator = new JsonNotation(JsonNotationType.NameSeperator);
        public readonly static JsonNotation MemberSeperator = new JsonNotation(JsonNotationType.MemberSeperator);
        #endregion

        #endregion
    }
}